package com.nku.mason.masonframework.core;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.nku.mason.masonframework.core.entities.Data;
import com.nku.mason.masonframework.core.entities.Handler;
import com.nku.mason.masonframework.core.entities.Param;
import com.nku.mason.masonframework.core.entities.View;
import com.nku.mason.masonframework.core.tools.BeanTool;
import com.nku.mason.masonframework.core.tools.ConfigTool;
import com.nku.mason.masonframework.core.tools.ControllerHelper;
import com.nku.mason.masonframework.util.ArrayUtil;
import com.nku.mason.masonframework.util.CodeUtil;
import com.nku.mason.masonframework.util.JSONUtil;
import com.nku.mason.masonframework.util.ReflectionUtil;
import com.nku.mason.masonframework.util.StreamUtil;
import com.nku.mason.masonframework.util.StringUtil;
/**
 * 请求转发器
 * @author Mason
 * @date 2017年3月15日
 */
@SuppressWarnings("unused")
@WebServlet(urlPatterns = "/*", loadOnStartup = 0)
public class DispatcherServlet extends HttpServlet{

	private static final long serialVersionUID = 7238850092928613314L;
	
	@Override
	public void init(ServletConfig config) throws ServletException{
		//初始化相关Helper类
		BootLoader.init();
		//获取ServletContext对象，用于Servlet注册
		ServletContext servletContext =config.getServletContext();
		//注册处理JSP的Servlet
		ServletRegistration jspServlet = servletContext.getServletRegistration("jsp");
		jspServlet.addMapping(ConfigTool.getAppJspPath() + "*");
		//注册处理静态资源的默认Servlet
		ServletRegistration defaultServlet = servletContext.getServletRegistration("default");
		defaultServlet.addMapping(ConfigTool.getAppAssetPath() + "*");
	}
	
	@Override
	public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		//获取请求方法与请求路径
		String requestMethod = req.getMethod().toLowerCase();
		String requestPath = req.getPathInfo();	//因为DispatcherServlet的urlPattern为"/*",所以getPathInfo()获得的是除去当前工程名(context)后面的路径
		
		//获取Action处理器
		Handler handler = ControllerHelper.getHandler(requestMethod, requestPath);
		if (handler != null) {
			//获取Controller类及其实例
			Class<?> controllerClass = handler.getControllerClass();
			Object controllerBean = BeanTool.getBean(controllerClass);
			//创建请求参数对象
			Map<String , Object> paramMap = new HashMap<String, Object>();
			Enumeration<String> parameterNames = req.getParameterNames();
			while (parameterNames.hasMoreElements()) {
				String paramName = (String) parameterNames.nextElement();
				String paramValue = req.getParameter(paramName);
				paramMap.put(paramName, paramValue);
			}
			
			//获取请求体中的参数,同样将其封装到paramMap中
//			String body = CodeUtil.decodeURL(StreamUtil.getString(req.getInputStream()));
//			if (!StringUtil.isEmpty(body)) {
//				String[] params = StringUtil.splitString(body, "&");
//				if (!ArrayUtil.isEmpty(params)) {
//					for(String param : params){
//						String[] strs = StringUtil.splitString(param, "=");
//						if (ArrayUtil.isEmpty(strs) && strs.length == 2) {
//							String paraName = strs[0];
//							String paramValue = strs[1];
//							paramMap.put(paraName, paramValue);
//						}
//					}
//				}
//			}
			
			Param param = new Param(paramMap);
			
			//调用Action方法
			Method actionMethod = handler.getActionMethod();
			Object result = ReflectionUtil.invokeMethod(controllerBean, actionMethod, param);
			
			//处理Action方法返回值
			if (result instanceof View) {
				//返回jsp页面
				View view = (View) result;
				String path = view.getPath();
				if (!StringUtil.isEmpty(path)) {
					if (path.startsWith("/")) {
						res.sendRedirect(req.getContextPath() + view.getPath());
					} else {
						Map<String, Object> model = view.getModel();
						if (model != null) {	//2017年3月16日13:53:02 bug1
							for(Map.Entry<String, Object> entry : model.entrySet()){
								req.setAttribute(entry.getKey(), entry.getValue());
							}
						}
						req.getRequestDispatcher(ConfigTool.getAppJspPath() + path).forward(req, res);
					}
				}
			} else if (result instanceof Data) {
				//返回JSON数据
				Data data = (Data) result;
				Object model = data.getModel();
				if (model != null) {
					res.setContentType("application/json");
					res.setCharacterEncoding("UTF-8");
					PrintWriter writer = res.getWriter();
					String json = JSONUtil.toJSON(model);
					writer.write(json);
					writer.flush();
					writer.close();
				}
			}
		}
		
	}
}






































































